package social.hub.facebook;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.ws.rs.core.MediaType;

import social.hub.util.UrlBuilder;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientHandlerException;
import com.sun.jersey.api.client.ClientRequest;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
import com.sun.jersey.api.client.filter.ClientFilter;
import com.sun.jersey.api.client.filter.LoggingFilter;
import com.sun.jersey.api.json.JSONConfiguration;

/**
 * https://developers.facebook.com/docs/reference/api/
 * 
 * @author Andre
 */
public class FacebookClientImpl implements FacebookClient {

	private String				accessToken;

	private Client				client;

	private static final String	SELF_ID				= "me";

	private static final String	API_URL_BASE		= "https://graph.facebook.com/";
	private static final String	PROFILE_URL_BASE	= API_URL_BASE + "{profileId}";
	private static final String	OBJECT_URL_BASE		= API_URL_BASE + "{objectId}";

	private static final String	FRIENDS_URL			= PROFILE_URL_BASE + "/friends";
	private static final String	FEEDS_URL			= PROFILE_URL_BASE + "/feed";
	private static final String	COMMENTS_URL		= OBJECT_URL_BASE + "/comments";
	private static final String	LIKES_URL			= OBJECT_URL_BASE + "/likes";
	private static final String	NOTES_URL			= PROFILE_URL_BASE + "/likes";
	private static final String	HOME_URL_BASE		= PROFILE_URL_BASE + "/home";

	public FacebookClientImpl(String accessToken) {

		this.accessToken = accessToken;

		ClientConfig clientConfig = new DefaultClientConfig();
		clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);

		client = Client.create(clientConfig);

		client.addFilter(new ClientFilter() {

			@Override
			public ClientResponse handle(ClientRequest request) throws ClientHandlerException {

				ClientResponse response = getNext().handle(request);

				List<String> list = response.getHeaders().get("content-type");

				String contentType = list.get(0);

				if (contentType.equals("text/javascript; charset=UTF-8")) {
					response.getHeaders().put("content-type",
							Collections.singletonList(MediaType.APPLICATION_JSON));
				}

				return response;

			}

		});

		client.addFilter(new LoggingFilter());

	}

	@Override
	public List<FacebookProfile> getFriends() {
		return getFriendsById(SELF_ID);
	}

	@Override
	public List<FacebookProfile> getFriends(Long facebookId) {
		return getFriendsById(facebookId.toString());
	}

	@Override
	public FacebookProfile getUserProfile() {
		return getUserProfileById(SELF_ID);
	}

	@Override
	public FacebookProfile getUserProfile(Long facebookId) {
		return getUserProfileById(facebookId.toString());
	}

	@Override
	public List<FacebookPost> getPosts() {
		return getPostsById(SELF_ID);
	}

	@Override
	public List<FacebookPost> getPosts(Long facebookId) {
		return getPostsById(facebookId.toString());
	}

	@Override
	public void sendDirectMessage(String text, Long toFacebookId) {
		sendDirectMessage(text, toFacebookId.toString());

	}

	@Override
	public void updateStatus(String status) {
		sendDirectMessage(status, SELF_ID);
	}

	private List<FacebookProfile> getFriendsById(String facebookId) {
		String url = new UrlBuilder(FRIENDS_URL).addUrlParan("profileId", facebookId)
				.addQueryParan("access_token", accessToken).toString();

		FacebookProfileList requestData = client.resource(url).get(FacebookProfileList.class);

		return requestData.getData();

	}

	private FacebookProfile getUserProfileById(String facebookId) {
		String url = new UrlBuilder(PROFILE_URL_BASE).addUrlParan("profileId", facebookId)
				.addQueryParan("access_token", accessToken).toString();
		return client.resource(url).get(FacebookProfile.class);
	}

	private void sendDirectMessage(String text, String toFacebookId) {
		String url = new UrlBuilder(FEEDS_URL).addUrlParan("profileId", toFacebookId)
				.addQueryParan("access_token", accessToken).toString();
		String body = "message=" + text;
		client.resource(url).post(body);
	}

	private List<FacebookPost> getPostsById(String facebookId) {

		String url = new UrlBuilder(HOME_URL_BASE).addUrlParan("profileId", facebookId)
				.addQueryParan("access_token", accessToken).toString();

		FacebookPostList facebookPostList = client.resource(url).get(FacebookPostList.class);

		List<FacebookPost> result = new ArrayList<FacebookPost>();

		for (FacebookPost facebookPost : facebookPostList.getData()) {

			if (facebookPost.getType().equals("status")) {
				result.add(facebookPost);
			}

		}

		return result;

	}
}
